package batch.process.checker.helper;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;

import batch.process.checker.DueDateChecker;
import batch.process.external.BatchProcessExternalAppFacade;
import batch.process.external.app.mailserver.BatchProcessMailServerApp;
import batch.process.utils.BatchProcessLogger;
import batch.process.utils.BatchProcessProperties;

public class DueDateCheckerHelper {

	private BatchProcessMailServerApp mailServer = null;	
	private static BatchProcessLogger logger = null;
	
	private String hostName = null;
	private int hostPort = 0;
	private String userName = null;
	private String password = null;
	private boolean sslReq = false;	
	private boolean debugMode = false;
	
	private String subject = null;
	private String text = null;
	private String[] to = null;
	private List attachments = null;
	
	public DueDateCheckerHelper() throws Exception {		
		try {
			logger = new BatchProcessLogger();
			init();			
			mailServer = BatchProcessExternalAppFacade.getMailServerInterface();
			mailServer.init(hostName, hostPort, userName,password, sslReq, debugMode);			
		} catch (Exception e) {
			logger.error(" Error on DueDateCheckerHelper ..." + e, DueDateCheckerHelper.class);
			e.printStackTrace();
			throw(e);
		}		
		
	}
	
	public boolean notifyDueDate() {
		String fees = null;
		boolean sucess = false;
		try {
			fees = getDueFees();
			if (fees != null && !fees.equals("")) {
				logger.info(" Found registered due dates for tomorrow " , DueDateChecker.class);
				sucess = mailServer.sendMail(subject, text + fees, userName, to,attachments);
				if (sucess) {
					logger.info(" Email notification successfully sent to " + Arrays.asList(to).toString()   , DueDateChecker.class);
				} else {
					logger.info(" Unable to send email notification to " + Arrays.asList(to).toString() , DueDateChecker.class);
				}
			} else {
				logger.info(" No due dates registered for tomorrow ...", DueDateCheckerHelper.class);			}
			
		} catch (Exception e) {
			sucess = false;
		}
		
		return(sucess);
	}
	
	private void initMailServerInfo() throws Exception{
		try {
			logger.info(" Reading key [MAIL_SERVER_HOST_NAME] ...", DueDateCheckerHelper.class);
			hostName = BatchProcessProperties.getProperty("MAIL_SERVER_HOST_NAME");
			
			logger.info(" Reading key [MAIL_SERVER_PORT] ...", DueDateCheckerHelper.class);
			hostPort = BatchProcessProperties.getInteger("MAIL_SERVER_PORT",25);
			
			logger.info(" Reading key [MAIL_SERVER_USER_NAME] ...", DueDateCheckerHelper.class);
			userName = BatchProcessProperties.getProperty("MAIL_SERVER_USER_NAME");
			
			logger.info(" Reading key [MAIL_SERVER_PASSWORD] ...", DueDateCheckerHelper.class);
			password = BatchProcessProperties.getProperty("MAIL_SERVER_PASSWORD");	
			
			logger.info(" Reading key [MAIL_SERVER_SSL_REQ] ...", DueDateCheckerHelper.class);
			sslReq = BatchProcessProperties.getBoolean("MAIL_SERVER_SSL_REQ");
			
			logger.info(" Reading key [MAIL_SERVER_DEBUG_MODE] ...", DueDateCheckerHelper.class);
			debugMode = BatchProcessProperties.getBoolean("MAIL_SERVER_DEBUG_MODE");
		} catch (Exception e) {
			logger.error(" Error initiating DueDateCheckerHelper mail server info ..." + e, DueDateCheckerHelper.class);
			throw(e);
		}
	}
	
	private void initMailInfo() throws Exception{
		try {
			logger.info(" Reading key [MAIL_SUBJECT] ...", DueDateCheckerHelper.class);
			subject = BatchProcessProperties.getProperty("MAIL_SUBJECT");
			
			logger.info(" Reading key [MAIL_TEXT] ...", DueDateCheckerHelper.class);
			text = BatchProcessProperties.getProperty("MAIL_TEXT") + "\n ";
			
			logger.info(" Reading key [MAIL_TO] ...", DueDateCheckerHelper.class);
			List<?> l = BatchProcessProperties.getList("MAIL_TO");
			
			to = l.toString().replace('[', ' ').replace(']', ' ').trim().split(", ");			
									
			logger.info(" Reading key [MAIL_ATTACHMENT_LSIT] ...", DueDateCheckerHelper.class);
			List attachPaths = BatchProcessProperties.getList("MAIL_ATTACHMENT_LSIT");
			
			if (attachPaths != null) {
				attachments = new ArrayList<File>();
				Iterator<String> it = attachPaths.iterator();
				while(it.hasNext()) {
					String filePath = it.next();
					
					File attachFile = new File(filePath);
					if(attachFile.exists()) {
						attachments.add(attachFile);
					}
				}
			}
			
		} catch (Exception e) {
			logger.error(" Error initiating DueDateCheckerHelper mail info ..." + e, DueDateCheckerHelper.class);
			throw(e);
		}
	}

	
	private void init() throws Exception {
		this.initMailServerInfo();
		this.initMailInfo();
	}
	
	private String getDueFees() {
		int today = 0;
		int tomorrow = 0;		
		List<?> dueDateList = null;
		StringBuffer result = new StringBuffer();
		
		try {
			today = GregorianCalendar.getInstance().get(Calendar.DAY_OF_MONTH) ;
			tomorrow = this.getActualNextDay(today);			
			dueDateList = BatchProcessProperties.getList(Integer.toString(tomorrow));
			Iterator<?> it = dueDateList.iterator();
			while (it.hasNext()) {
				String str = (String)it.next();
				if (!str.trim().equals("")) {
					result.append(" - " + str + "\n");
				}
			}						
		} catch (Exception e) {
			logger.error(" Error upon creating due fees string : " + e, DueDateCheckerHelper.class);
		} finally {
			
		}
		return result.toString();
	}
	
	private int getActualNextDay(int today) {		
		int tomorrow = today + 1;
		int nextDay = 0;
		try {
			if (Calendar.FEBRUARY == Calendar.MONTH) {
				if ( Calendar.YEAR%4 == 0) {
					if (tomorrow > 29) {
						nextDay = 1;
					} else {
						nextDay = tomorrow;
					}					
				} else {
					if (tomorrow > 28) {
						nextDay = 1;
					} else {
						nextDay = tomorrow;
					}
				}
			} else {
				if (tomorrow > 31) {
					nextDay = 1;
				} else {
					nextDay = tomorrow;
				}
			}
		} catch (Exception e) {
			logger.error(" Error acquiring next day date : " + e, DueDateCheckerHelper.class);
		}
		return(nextDay);
	}
	
	
	
}
